package com.hongxin.nw.netty.model.packing;

import com.hongxin.nw.netty.utils.FieldPack;
import com.hongxin.nw.netty.values.TypeIdentif;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * @remark 7.1.2应用规约控制信息（APCI)的定义
 * 应用规约控制信息（APCI）的定义如图3所示。每个APCI包括下列的定界元素：一个启动字符，APDU的长度，以及控制域，可以传送一个完整的APDU（或者，出于控制目的，仅仅是传送APCI域）。
 * @author: GuoXiaolin
 * @date 2019/5/16 18:07
 * @Version 1.0
 * @Descibe
 */
@Slf4j
@Getter
@Setter
public class APCI {

    private String identifyStart;//起始符号:固定为68H
    private String APDULength;//APDU长度域,2个八位位组,apci+asdu
    private String conArea;//控制域,4个八位位组

    public String getHexData(){
        return this.identifyStart + this.APDULength + this.conArea;
    }
    public APCI setIdentifyStart(Integer identifyStart) {
        this.identifyStart = String.valueOf(identifyStart);
        return this;
    }
    /**
     * 第一个八位位组b1
     * 第二个八位位组b2
     * 第三个八位位组b3
     * 第四个八位位组b4
     * @param format 格式
     * @param type 类型
     * @return 返回
     */
    public APCI setConArea(final String format, final int type) {

        int b1  = 0b00000000;
        int b2  = 0b00000000;
        int b3  = 0b00000000;
        int b4  = 0b00000000;
        if (format.equals(TypeIdentif.FORMAT_I.getStr())){
            b1 = 0b00100000;
            b2 = 0b00000000;
            b3 = 0b00000000;
            b4 = 0b00000000;
        }
        if (format.equals(TypeIdentif.FORMAT_S.getStr())){
            b1 = 0b00000001;
            b2 = 0b00000000;
            b3 = 0b00000000;
            b4 = 0b00000000;
        }
        if (format.equals(TypeIdentif.FORMAT_U.getStr())){
            b1 = type;
            b2 = 0b00000000;
            b3 = 0b00000000;
            b4 = 0b00000000;
        }
        String sb1 = FieldPack.caseToBin(String.valueOf(b1),2);
        String sb2 = FieldPack.caseToBin(String.valueOf(b2),2);
        String sb3 = FieldPack.caseToBin(String.valueOf(b3),2);
        String sb4 = FieldPack.caseToBin(String.valueOf(b4),2);
        this.conArea = sb1 + sb2 + sb3 + sb4;
        return this;
    }

    public APCI setAPDULength(final int length) throws Exception  {
        if (length > 2047){
            throw new Exception("APDU 长度不能超过2047字节");
        }
        this.APDULength = FieldPack.caseToBin(String.valueOf(length), TypeIdentif.BYTE_LENGTH_DOMAIN.getByteLength());
        return this;
    }

    @Override
    public String toString() {
        return "APCI{" +
                "identifyStart='" + identifyStart + '\'' +
                ", APDULength='" + APDULength + '\'' +
                ", conArea='" + conArea + '\'' +
                '}';
    }
}
